﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Collections;

namespace HDAPI
{
    /// <summary>
    /// Utility Class to access keys from appsettings section of web.config file
    /// </summary>
    public class Globals
    {
        static int DefaultReadTimeOut = 5;
        static int DefaultConnectTimeOut = 5;

        /// <summary>
        /// Gets the value for the specified key
        /// Key will be defined in the appSettings section of web.config
        /// </summary>
        /// <param name="Key"></param>
        public static string GetValue(string Key)
        {
            return System.Configuration.ConfigurationManager.AppSettings[Key];
        }

        /// <summary>
        /// API key will be defined in the appSettings section of web.config
        /// Default value is taken if no value is specified in web.config: 51ce43021c8109c7f7054e709b0f7514
        /// </summary>
        public static string ApiKey
        {
            get
            {
                if (string.IsNullOrEmpty(GetValue("ApiKey".ToLower())))
                {
                    return "51ce43021c8109c7f7054e709b0f7514";
                }
                else
                {
                    return GetValue("ApiKey".ToLower());
                }
            }
        }

        /// <summary>
        /// Where we will post our queries
        /// </summary>
        public static string ServerUrl
        {
            get
            {
                string srv_url = GetValue("ServerUrl");
                if (srv_url.EndsWith("/"))
                    srv_url = srv_url.Substring(0, srv_url.Length - 1);
                srv_url = srv_url.Replace("http://", "");

                //resolve the server name into IP address list and pick one random server IP
                IPHostEntry objIPHostEntry = Dns.Resolve(srv_url);
                Console.WriteLine(objIPHostEntry.AddressList);
                Random randomValue = new Random();

                List<IPAddress> arrIPAddresses = new List<IPAddress>();
                foreach (IPAddress address in objIPHostEntry.AddressList)
                {
                    arrIPAddresses.Add(address);
                }
                int tries = arrIPAddresses.Count;

                while (arrIPAddresses.Count != 0)
                {
                    IPAddress address = arrIPAddresses[randomValue.Next(0, arrIPAddresses.Count)];
                    arrIPAddresses.Remove(address);

                    //check if the connection to server is availale
                    if (isServerUp(address.ToString(), 80, Globals.ConnectTimeOut * 1000))
                    {
                        return address.ToString();
                    }
                }

                if (arrIPAddresses.Count == 0)
                {
                    throw new Exception("HDAPI Server is unreachable: " + srv_url + ", retry count:" + tries);
                }
                return srv_url;//none found
            }
        }

        /// <summary>
        /// User Email address used to connect to the handsetdetection.com server
        /// </summary>
        public static string Email
        {
            get
            {
                return GetValue("Email".ToLower());
            }
        }

        /// <summary>
        /// Secret value provided
        /// </summary>
        public static string Secret
        {
            get
            {
                return GetValue("Secret".ToLower());
            }
        }

        /// <summary>
        /// Read timeout in seconds
        /// </summary>
        public static int ReadTimeOut
        {
            get
            {
                try
                {
                    if (GetValue("ReadTimeOut") != null)
                    {
                        return Convert.ToInt32(GetValue("ReadTimeOut".ToLower()));
                    }
                    else
                    {
                        return DefaultReadTimeOut;
                    }
                }
                catch
                {
                    return DefaultReadTimeOut;
                }
            }
        }


        /// <summary>
        /// Connect timeout in seconds
        /// </summary>
        public static int ConnectTimeOut
        {
            get
            {
                try
                {

                    if (GetValue("ConnectTimeOut") != null)
                    {
                        return Convert.ToInt32(GetValue("ConnectTimeOut".ToLower()));
                    }
                    else
                    {
                        return DefaultConnectTimeOut;
                    }
                }
                catch
                {
                    return DefaultConnectTimeOut;
                }
            }
        }

        /// <summary>
        /// Gets the SiteID 
        /// reference: http://www.handsetdetection.com/sites/index
        /// </summary>
        public static string SiteID
        {
            get
            {
                return GetValue("SiteID".ToLower());
            }
        }

        /// <summary>
        /// Determines whether proxy server is used for API calls to connect to the handsetdetection.com server
        /// </summary>
        public static bool Use_Proxy
        {
            get
            {
                try
                {
                    return Convert.ToBoolean(GetValue("Use_Proxy"));
                }
                catch
                {
                    return false;
                }

            }
        }

        /// <summary>
        /// IP Address of the proxy server
        /// </summary>
        public static string Proxy_Server
        {
            get { return GetValue("Proxy_Server"); }
        }

        /// <summary>
        /// Port number to connect to the proxy server
        /// </summary>
        public static int Proxy_Port
        {
            get
            {
                try
                {
                    return Convert.ToInt32(GetValue("Proxy_Port"));
                }
                catch
                {
                    return 80;
                }
            }
        }

        /// <summary>
        /// Username to connect to the proxy server
        /// </summary>
        public static string Proxy_User
        {
            get { return GetValue("Proxy_User"); }
        }

        /// <summary>
        /// Password to connect to the proxy server
        /// </summary>
        public static string Proxy_Pass
        {
            get { return GetValue("Proxy_Pass"); }
        }

        #region "Public functions"
        /// <summary>
        /// To check whether particular server is online/reachable
        /// </summary>
        /// <param name="ip">IP Address</param>
        /// <param name="port">Port number</param>
        /// <param name="timout">Timeout in miliseconds</param>
        /// <returns></returns>
        public static bool isServerUp(string ip, int port, int timout)
        {
            IPAddress validIP;
            if (IPAddress.TryParse(ip, out validIP))
            {
                IPEndPoint remoteEndPoint = new IPEndPoint(validIP, port);
                bool flag = TimeoutChecker.Connect(remoteEndPoint, timout);
                return flag;
            }
            else
            {
                return false;
            }
        }
        #endregion
    }
}
